Skip to content

chore: seed parity-manifest.json (Layer 2 of parity discipline)#24

Merged
govindkavaturi-art merged 1 commit intomainfrom
chore/parity-manifest-seed
May 4, 2026
Merged

chore: seed parity-manifest.json (Layer 2 of parity discipline)#24
govindkavaturi-art merged 1 commit intomainfrom
chore/parity-manifest-seed

Conversation

@mikemolinet
Copy link
Copy Markdown
Collaborator

Summary

First-pass audit of cueapi-sdk coverage against the hosted CueAPI API. Layer 2 of the 3-layer parity discipline:

  1. PR template in private monorepo — landed via cueapi/cueapi#615
  2. This manifest + cueapi-cli equivalent — Layer 2
  3. Backlog rows for each port — operational on https://trydock.ai/mike/agent-team-project-tracker?m=sheet&s=backlog

What's in the manifest

  • 14 endpoints currently covered by the SDK
  • 12 endpoints missing — including cue.fire (real ergonomic gap; team-comm relies on it), execution.replay, the entire worker-pull surface, usage, webhook-secret retrieval, and the entire Phase 12.1.5 messaging primitive (Identity / Messages / Inbox)
  • Cue model has 8 missing fields shipped in private over recent months: delivery, alerts, catch_up, verification, on_success_fire, require_payload_override, required_payload_keys, stats. Plus CueDetailResponse (executions list + pagination) is missing
  • Execution has no dedicated model class — SDK returns dicts; should promote to a typed class with outcome / evidence / heartbeat / chain fields
  • Worker, Agent, Message classes missing entirely

Why now

Mike (CueAPI overseer) flagged 2026-05-03 that hosted features were drifting out of the packages. Two PRs from yesterday (private monorepo #589 — expose payload on GET executions; #590 — require_payload_override enforcement) have explicit Backlog rows pending port to this SDK. Per the new PR template, future hosted PRs will flag SDK ports at PR-time, not after.

How to use this

  • Per-PR: hosted-monorepo PRs touching covered surfaces (endpoints in endpoints_covered or fields in model_drift.*.covered_fields) flag the SDK in their Parity Impact section. Author opens a Backlog row with lead_agent=cueapi and depends_on: <hosted PR> merge.
  • Monthly: full audit pass updates last_full_audit and sdk_version_at_audit. Items move from endpoints_missingendpoints_covered as they get ported.

Test plan

  • JSON syntax valid (loaded into Python's json module without error)
  • No code-level test — this is a documentation/audit artifact

Parity impact

This is a meta-file in the SDK repo, not a code change.

🤖 Generated with Claude Code

First-pass audit of cueapi-sdk coverage against the hosted CueAPI API.
Catalogues which endpoints + model fields the SDK covers, and which
have drifted out of sync.

The manifest is the audit checklist. New PRs in the private monorepo
that touch covered surfaces flag this manifest in their Parity Impact
section (see private repo's `.github/pull_request_template.md`).
Monthly full sweep updates `last_full_audit`.

Notable drift surfaced:

- 12 endpoints missing (cue.fire, execution.replay, worker registration
  + claim flow, usage, webhook-secret retrieval, plus the entire
  messaging primitive surface from Phase 12.1.5 — Identity / Messages /
  Inbox).
- Cue model missing 8 fields shipped in private over the last few
  months: delivery, alerts, catch_up, verification, on_success_fire,
  require_payload_override, required_payload_keys, stats. CueDetailResponse
  shape (executions list + pagination) also missing.
- Execution has no dedicated model class — SDK returns dicts. Should
  promote to a typed class along with the outcome / evidence /
  heartbeat / chain attribution fields.
- Worker, Agent, Message classes missing entirely.

Two PRs from 2026-05-03 (private repo #589 expose payload on GET
executions; #590 require_payload_override enforcement) have explicit
Backlog rows pending port to this SDK; both are priority=now once
their source PRs merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@govindkavaturi-art govindkavaturi-art left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same high-quality parity-manifest pattern as cueapi-mcp#13 + cueapi-cli#25. The drift-tracking section flagging POST /v1/cues/{id}/fire as 'Real ergonomic gap' (with the cross-link to #590's require_payload_override port) is exactly the kind of cross-package signal this primitive enables. Approve.

@govindkavaturi-art govindkavaturi-art merged commit 346feca into main May 4, 2026
3 of 4 checks passed
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
Closes the Cue portion of cueapi-python #24's `model_drift` manifest.
The SDK's Cue Pydantic model was silently dropping 8 fields the server
returns (Pydantic default extra="ignore"); callers reading e.g. the
``catch_up`` policy or ``stats`` blob via the SDK got nothing.

Fields added (all Optional with defaults so legacy responses still
parse):

- delivery: Optional[DeliveryConfig]    — timeout_seconds, outcome_deadline_seconds
- alerts: Optional[AlertConfig]          — extra="allow" forward-compat
- catch_up: Optional[str]                — run_once_if_missed / skip_missed / replay_all
- verification: Optional[VerificationConfig]  — mode + required_assertions; extra="allow"
- on_success_fire: Optional[str]         — cue ID for 1:1 chaining (Gap 1)
- require_payload_override: bool = False — hosted PR #590; default False matches server
- required_payload_keys: Optional[List[str]]  — hosted PR #590
- stats: Optional[Dict[str, Any]]        — CueDetailResponse-only blob (7d success rate etc.)

Three new nested models:

- DeliveryConfig: typed schema for the 2-phase delivery config
- AlertConfig:    forward-compat (extra="allow") since alert kinds
                  evolve server-side
- VerificationConfig: typed `mode` + `required_assertions` plus
                  extra="allow" for forward-compat on assertion kinds

Tests: 11 new (30 → 41 unit tests). Coverage:

- Old response (without new fields) still parses cleanly — pinning
  backward compat
- Each new field round-trips correctly with a realistic payload
- AlertConfig forward-compat: unknown server-side keys land in
  model_extra without raising
- VerificationConfig forward-compat: same
- Full-response roundtrip with every field set
- CueList parses correctly with new fields in each row

No breaking change for SDK callers — fields are additive, all
Optional/defaulted, server's prior shape still parses. Bump warranted
at next minor (0.3.0) for the new accessor surface.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
…y() (#25)

Two changes, both in ExecutionsResource:

(1) **Bug fix — mark_verified silently dropped both kwargs.** The prior
    implementation accepted ``valid`` and ``reason`` as keyword args but
    always sent ``json={}``. The server treats absent body as
    ``valid=true``, so the default-arg path produced the right outcome
    by accident — but every caller passing ``valid=False`` or
    ``reason="..."`` got ``verified_success`` instead of their intent,
    silently. The fix builds the body explicitly:

      body = {"valid": valid}
      if reason is not None:
          body["reason"] = reason

    Pinned by 4 regression tests:
    - default-arg sends ``{"valid": True}`` (not ``{}``)
    - ``valid=False`` lands in body
    - ``reason="..."`` lands in body
    - ``reason=None`` is omitted (not serialized as null)

(2) **New: ``ExecutionsResource.replay(execution_id)``** — POST
    /v1/executions/{id}/replay. Closes one of the
    ``endpoints_missing`` entries from cueapi-python #24's parity
    manifest. Server-side already shipped on prod; this is pure SDK
    catch-up.

    Returns the server's response dict unchanged (new execution_id,
    scheduled_for, status, triggered_by="replay", replayed_from).

Tests: 5 new (12 → 17 total). All pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
…/v1/usage) (#26)

Closes 2 entries from cueapi-python #24's `endpoints_missing` parity manifest:

- GET /v1/workers           → client.workers.list()
- DELETE /v1/workers/{id}   → client.workers.delete(worker_id)
- GET /v1/usage             → client.usage.get()

(`DELETE /v1/workers/{id}` wasn't in the manifest but is part of the same
hosted surface — added for completeness.)

New resource classes:

- `cueapi/resources/workers.py`: WorkersResource — `.list()` + `.delete()`
- `cueapi/resources/usage.py`:   UsageResource — `.get()`

Both registered on the CueAPI client and exported from cueapi.__init__.

Skipped from manifest: POST /v1/worker/heartbeat (worker registration).
The hosted endpoint is meant for cueapi-worker (which already wraps it
correctly with heartbeat-loop semantics); direct SDK-driven registration
is redundant. Documented in WorkersResource's class docstring.

Tests: 5 new (12 → 17 unit tests). Mock-based, mirrors the existing
ExecutionsResource test pattern.

The 14 pre-existing staging-cred test_cues.py failures (`ValueError:
api_key is required`) are unrelated to this PR — same flake captured in
the Backlog row added when surveying cueapi-python earlier this session.

No hosted-PR dependency. All 3 endpoints already shipped on prod.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
Wraps the entire `/v1/agents` surface from the messaging primitive
(Phase 12.1.5). Closes the agents portion of the `Messaging primitive`
endpoints_missing entry in cueapi-python #24's parity manifest. The
companion `MessagesResource` (send/get/read/ack lifecycle) ships in a
follow-up PR.

New resource:

- `cueapi/resources/agents.py`: AgentsResource
  - .create(display_name, slug=None, webhook_url=None, metadata=None)
  - .list(status=None, include_deleted=False, limit=50, offset=0)
  - .get(ref, include_deleted=False)
  - .update(ref, display_name=None, webhook_url=None, clear_webhook_url=False,
           status=None, metadata=None)
  - .delete(ref)
  - .webhook_secret_get(ref)
  - .webhook_secret_regenerate(ref)  # sends X-Confirm-Destructive: true
  - .inbox(ref, state=None, limit=50, offset=0)
  - .sent(ref, limit=50, offset=0)

Client extension:

- `client._request` now accepts an optional `headers` kwarg, which
  extends (does not replace) the client's default Authorization +
  Content-Type + User-Agent headers. Used here for the destructive
  X-Confirm-Destructive guard; will also be used by the upcoming
  MessagesResource for X-Cueapi-From-Agent + Idempotency-Key.

Design notes pinned by tests:

- `--include-deleted` mirror: `include_deleted=True` sends `"true"`,
  `False` (default) omits. Same omit-when-default pattern as PR #26's
  `executions list --has-evidence`.

- `clear_webhook_url=True` sends literal JSON `null` (key present,
  value None), NOT field omission. Server uses `model_fields_set` to
  disambiguate "omitted = no change" from "explicit null = clear", so
  the SDK MUST send the key with explicit None. Pinned by
  test_clear_webhook_url_sends_explicit_null.

- `webhook_url` and `clear_webhook_url` mutex enforced with a clear
  ValueError before any HTTP call.

- `webhook_secret_regenerate` sends X-Confirm-Destructive: true in
  the header. The server requires it; the SDK adds it automatically
  so callers don't have to know about the header. Pinned by
  test_regenerate_sends_destructive_header.

Tests: 18 new across 9 test classes (12 → ~30 unit tests; total 46
passing across all unit-test files).

No hosted-PR dependency. All 9 endpoints already shipped on prod.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
Wraps the entire `/v1/agents` surface from the messaging primitive
(Phase 12.1.5). Closes the agents portion of the `Messaging primitive`
endpoints_missing entry in cueapi-python #24's parity manifest. The
companion `MessagesResource` (send/get/read/ack lifecycle) ships in a
follow-up PR.

New resource:

- `cueapi/resources/agents.py`: AgentsResource
  - .create(display_name, slug=None, webhook_url=None, metadata=None)
  - .list(status=None, include_deleted=False, limit=50, offset=0)
  - .get(ref, include_deleted=False)
  - .update(ref, display_name=None, webhook_url=None, clear_webhook_url=False,
           status=None, metadata=None)
  - .delete(ref)
  - .webhook_secret_get(ref)
  - .webhook_secret_regenerate(ref)  # sends X-Confirm-Destructive: true
  - .inbox(ref, state=None, limit=50, offset=0)
  - .sent(ref, limit=50, offset=0)

Client extension:

- `client._request` now accepts an optional `headers` kwarg, which
  extends (does not replace) the client's default Authorization +
  Content-Type + User-Agent headers. Used here for the destructive
  X-Confirm-Destructive guard; will also be used by the upcoming
  MessagesResource for X-Cueapi-From-Agent + Idempotency-Key.

Design notes pinned by tests:

- `--include-deleted` mirror: `include_deleted=True` sends `"true"`,
  `False` (default) omits. Same omit-when-default pattern as PR #26's
  `executions list --has-evidence`.

- `clear_webhook_url=True` sends literal JSON `null` (key present,
  value None), NOT field omission. Server uses `model_fields_set` to
  disambiguate "omitted = no change" from "explicit null = clear", so
  the SDK MUST send the key with explicit None. Pinned by
  test_clear_webhook_url_sends_explicit_null.

- `webhook_url` and `clear_webhook_url` mutex enforced with a clear
  ValueError before any HTTP call.

- `webhook_secret_regenerate` sends X-Confirm-Destructive: true in
  the header. The server requires it; the SDK adds it automatically
  so callers don't have to know about the header. Pinned by
  test_regenerate_sends_destructive_header.

Tests: 18 new across 9 test classes (12 → ~30 unit tests; total 46
passing across all unit-test files).

No hosted-PR dependency. All 9 endpoints already shipped on prod.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
Wraps the `/v1/messages` surface (Phase 12.1.5). Closes the messages
portion of the `Messaging primitive` `endpoints_missing` entry in
cueapi-python #24's parity manifest.

New resource:

- `cueapi/resources/messages.py`: MessagesResource
  - .send(from_agent, to, body, subject=, reply_to=, priority=,
          expects_reply=, reply_to_agent=, metadata=, idempotency_key=)
  - .get(msg_id)
  - .mark_read(msg_id)   # idempotent on already-read
  - .ack(msg_id)         # terminal

Client extension:

- Same `_request(headers=...)` extension as PR #27 (AgentsResource).
  Independent commit on this branch since the two resources can land
  in either order; minor merge conflict on client.py is auto-resolvable
  (both PRs add the same kwarg in the same way).

Design notes pinned by tests:

- `from_agent` goes via `X-Cueapi-From-Agent` HEADER, NOT in body.
  The server's MessageCreate schema is extra="forbid" — putting `from`
  in the body would 400, but we want this caught at unit-test time.
  Pinned by test_minimal_body_and_from_header.

- `expects_reply=False` (default) NOT sent in body. Server default
  is False; sending `expects_reply: false` is no-op + adds noise.
  Pinned by test_omits_expects_reply_when_default.

- `idempotency_key` >255 chars raises ValueError client-side BEFORE
  any HTTP call. Matches server's hard limit. Pinned that no HTTP
  request is made when the validation fails.

- `idempotency_key=None` omits the header entirely (no `Idempotency-Key:
  None` leakage). Pinned.

Tests: 9 new (12 → 21 in this resource family; 38 total across all
unit-test files).

Server-side dedup-hit (200 response) and priority-downgrade signals
(`X-CueAPI-Priority-Downgraded` header) are surfaced through the
underlying httpx response — the SDK's `_handle_response` returns the
data dict on 2xx, so callers see status_code 200 vs 201 only via the
underlying client. A future enhancement could expose these signals
explicitly via a richer return type; documented for follow-up.

No hosted-PR dependency. All 4 endpoints already shipped on prod.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art pushed a commit that referenced this pull request May 4, 2026
Wraps the `/v1/messages` surface (Phase 12.1.5). Closes the messages
portion of the `Messaging primitive` `endpoints_missing` entry in
cueapi-python #24's parity manifest.

New resource:

- `cueapi/resources/messages.py`: MessagesResource
  - .send(from_agent, to, body, subject=, reply_to=, priority=,
          expects_reply=, reply_to_agent=, metadata=, idempotency_key=)
  - .get(msg_id)
  - .mark_read(msg_id)   # idempotent on already-read
  - .ack(msg_id)         # terminal

Client extension:

- Same `_request(headers=...)` extension as PR #27 (AgentsResource).
  Independent commit on this branch since the two resources can land
  in either order; minor merge conflict on client.py is auto-resolvable
  (both PRs add the same kwarg in the same way).

Design notes pinned by tests:

- `from_agent` goes via `X-Cueapi-From-Agent` HEADER, NOT in body.
  The server's MessageCreate schema is extra="forbid" — putting `from`
  in the body would 400, but we want this caught at unit-test time.
  Pinned by test_minimal_body_and_from_header.

- `expects_reply=False` (default) NOT sent in body. Server default
  is False; sending `expects_reply: false` is no-op + adds noise.
  Pinned by test_omits_expects_reply_when_default.

- `idempotency_key` >255 chars raises ValueError client-side BEFORE
  any HTTP call. Matches server's hard limit. Pinned that no HTTP
  request is made when the validation fails.

- `idempotency_key=None` omits the header entirely (no `Idempotency-Key:
  None` leakage). Pinned.

Tests: 9 new (12 → 21 in this resource family; 38 total across all
unit-test files).

Server-side dedup-hit (200 response) and priority-downgrade signals
(`X-CueAPI-Priority-Downgraded` header) are surfaced through the
underlying httpx response — the SDK's `_handle_response` returns the
data dict on 2xx, so callers see status_code 200 vs 201 only via the
underlying client. A future enhancement could expose these signals
explicitly via a richer return type; documented for follow-up.

No hosted-PR dependency. All 4 endpoints already shipped on prod.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants